"""Database CRUD helpers."""
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from . import models, utils


async def get_activation_code_for_update(db: AsyncSession, raw_code: str):
    code_hash = utils.hash_code(raw_code)
    stmt = select(models.ActivationCode).where(models.ActivationCode.code_hash == code_hash).with_for_update()
    result = await db.execute(stmt)
    return result.scalars().first()


async def get_license(db: AsyncSession, code_id: int, device_hash: str):
    stmt = select(models.License).where(models.License.code_id == code_id, models.License.device_hash == device_hash)
    result = await db.execute(stmt)
    return result.scalars().first()


async def get_license_by_code_and_device(db: AsyncSession, raw_code: str, device_hash: str):
    code_hash = utils.hash_code(raw_code)
    stmt = select(models.License).join(models.ActivationCode).where(
        models.ActivationCode.code_hash == code_hash,
        models.License.device_hash == device_hash
    )
    result = await db.execute(stmt)
    return result.scalars().first()


async def get_license_by_hash_and_device(db: AsyncSession, activation_code_hash: str, device_hash: str):
    """Get license by activation code hash (for enhanced check endpoint)."""
    stmt = select(models.License).join(models.ActivationCode).where(
        models.ActivationCode.code_hash == activation_code_hash,
        models.License.device_hash == device_hash
    )
    result = await db.execute(stmt)
    return result.scalars().first()


async def get_license_count(db: AsyncSession, code_id: int) -> int:
    stmt = select(func.count()).select_from(models.License).where(models.License.code_id == code_id)
    result = await db.execute(stmt)
    return result.scalar_one()


async def create_license(db: AsyncSession, code_id: int, device_hash: str, expires_at):
    lic = models.License(code_id=code_id, device_hash=device_hash, expires_at=expires_at)
    db.add(lic)
    await db.commit()
    await db.refresh(lic)
    return lic


async def disable_activation_code(db: AsyncSession, raw_code: str) -> bool:
    """Disables an activation code. Returns True on success, False if not found."""
    code_hash = utils.hash_code(raw_code)
    stmt = select(models.ActivationCode).where(models.ActivationCode.code_hash == code_hash)
    result = await db.execute(stmt)
    code_obj = result.scalars().first()
    if not code_obj:
        return False
    code_obj.enabled = False
    await db.commit()
    return True

async def create_activation_code_db(db: AsyncSession, comment: str, duration_days, quota: int) -> str:
    raw_code = utils.generate_raw_code()
    code_hash = utils.hash_code(raw_code)
    ac = models.ActivationCode(raw_code=raw_code, code_hash=code_hash, duration_days=duration_days, quota=quota, comment=comment)
    db.add(ac)
    await db.commit()
    return raw_code
